package com.chenyi.data.structure.queue;

/**
 * @author by chenyi
 * @className RingArrayQuere
 * @date 2021/12/18 11:17
 */

public class RingArrayQueue implements Queue{
    /**
     * 队列最大容量
     */
    private int maxSize;

    /**
     * 队列头
     */
    private int front;

    /**
     * 队列尾
     */
    private int rear;

    /**
     * 存放队列数据
     */
    private int[] arr;

    public RingArrayQueue(int maxSize) {
        this.maxSize = maxSize + 1;
        arr = new int[this.maxSize];
        this.front = 0;
        this.rear = 0;
    }

    /**
     * 判断队列是否已满
     * @return
     */
    @Override
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    /**
     * 判断队列是否为空
     * @return
     */
    @Override
    public boolean isEmpty() {
        return this.front == this.rear;
    }

    /**
     * 添加队列
     * @param e
     * @return
     */
    @Override
    public boolean addQueue(int e) {
        // 判断队列是否已满
        if (isFull()) {
            System.out.println("队列已满无法添加队列");
            return false;
        }
        arr[rear] = e;
        rear = (rear + 1) % maxSize;
        return true;
    }

    /**
     * 获取队列
     * @return
     */
    @Override
    public int getQueue() {
        // 判断队列是否为空
        if (isEmpty()) {
            throw new RuntimeException("队列为空无法获取数据");
        }
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }

    /**
     * 展示队列
     */
    @Override
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空无法获取数据");
            return;
        }
        for (int i = front; i < front + size(); i++) {
            System.out.printf("queue[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    /**
     * 显示队列的头数据
     * @return
     */
    @Override
    public int peekHeadQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空无法获取数据");
        }
        return this.arr[front];
    }

    /**
     * 获取当前队列有效个数
     * @return
     */
    public int size() {
        return (rear + maxSize - front) % maxSize;
    }
}
